<?php
namespace plugins\HuaweiObs;

use app\common\controller\Plugin;
use app\admin\model\Attachment as AttachmentModel;
use think\Db;
use think\facade\Env;
use think\Image;

require Env::get('root_path').'plugins/HuaweiObs/SDK/obs-autoloader.php';
use Obs\ObsClient;

class HuaweiObs extends Plugin
{
    private $obsClient;

    /**
     * @var array 插件信息
     */
    public $info = [
        // 插件名[必填]
        'name'        => 'HuaweiObs',
        // 插件标题[必填]
        'title'       => '华为云OBS上传插件',
        // 插件唯一标识[必填],格式：插件名.开发者标识.plugin
        'identifier'  => 'huawei_obs.zrf.plugin',
        // 插件图标[选填]
        'icon'        => 'fa fa-fw fa-upload',
        // 插件描述[选填]
        'description' => '需将【<a href="/admin.php/admin/system/index/group/upload.html">上传驱动</a>】将其设置为"华为云OBS"。在附件管理中删除文件，并不会同时删除华为云OBS上的文件。',
        // 插件作者[必填]
        'author'      => 'rocky',
        // 作者主页[选填]
        'author_url'  => '',
        // 插件版本[必填],格式采用三段式：主版本号.次版本号.修订版本号
        'version'     => '1.0.0',
        // 是否有后台管理功能[选填]
        'admin'       => '0',
    ];

    /**
     * @var array 插件钩子
     */
    public $hooks = [
        'upload_attachment'
    ];

    /**
     * 上传附件
     * @param array $params 参数
     * @return mixed
     */
    public function uploadAttachment($params = [])
    {

        $params['module'] = $params['module'] ? $params['module'] : input('module');//解决获取不到module参数

        $file = $params['file'];

        // 缩略图参数
        $thumb = request()->post('thumb', '');

        $config = $this->getConfigValue();
        $error_msg = '';
        if ($config['key'] == '') {
            $error_msg = '未填写华为云OBS【AccessKey】';
        } elseif ($config['secret'] == '') {
            $error_msg = '未填写华为云OBS【SecretKey】';
        } elseif ($config['bucket'] == '') {
            $error_msg = '未填写华为云OBS桶名称';
        } elseif ($config['endpoint'] == '') {
            $error_msg = '未填写华为云OBS【Endpoint】';
        } elseif ($config['domain'] == '') {
            $error_msg = '未填写访问域名';
        }

        if ($error_msg != '') {
            switch ($params['from']) {
                case 'wangeditor':
                    return "error|{$error_msg}";
                    break;
                case 'ueditor':
                    return json(['state' => $error_msg]);
                    break;
                case 'editormd':
                    return json(["success" => 0, "message" => $error_msg]);
                    break;
                case 'ckeditor':
                    return ck_js(request()->get('CKEditorFuncNum'), '', $error_msg);
                    break;
                case 'layim':
                    return json(['code'   => 1, 'msg'   => $error_msg, 'data' => []]);
                    break;
                default:
                    return json([
                        'code'   => 0,
                        'class'  => 'danger',
                        'info'   => $error_msg
                    ]);
            }
        }



        // TODO 不用先上传本地 文件提交后的对象可以直接上传
        // 移动到框架应用根目录/uploads/ 目录下
        $info = $file->move(config('upload_path') . DIRECTORY_SEPARATOR . 'temp', '');

        // 文件信息
        $file_info = $file->getInfo();

        // 要上传文件的本地路径
        $localfile = $info->getPathname();

        // 上传到OBS后保存的文件名
        $file_name = explode('.', $file_info['name']);
        $ext = end($file_name);

        if(!empty($config['dir'])){
            $oss_dir = $config['dir'] . '/';
        }
        $key = $oss_dir . date('Ymd') . '/' .$info->hash('md5').'.'.$ext;

        // 创建ObsClient实例
        $this->obsClient = new ObsClient([
            'key' => $config['key'],
            'secret' => $config['secret'],
            'endpoint' => rtrim($config['endpoint'], '/'),
        ]);

        $res = $this->obsClient->putObject([
            'Bucket' => $config['bucket'],
            'Key' => $key,
            'SourceFile' => $localfile   // localfile为待上传的本地文件路径，需要指定到具体的文件名
        ]);




        if (!isset($res['RequestId'])) {
            switch ($params['from']) {
                case 'wangeditor':
                    return "error|上传失败";
                    break;
                case 'ueditor':
                    return json(['state' => '上传失败']);
                    break;
                case 'editormd':
                    return json(["success" => 0, "message" => '上传失败']);
                    break;
                case 'ckeditor':
                    return ck_js(request()->get('CKEditorFuncNum'), '', '上传失败');
                    break;
                case 'layim':
                    return json(['code'   => 1, 'msg'   => '上传失败', 'data' => []]);
                    break;
                default:
                    return json([
                        'code'   => 0,
                        'class'  => 'danger',
                        'info'   => '上传失败'
                    ]);
            }
        } else {
            // 图片宽度
            $img_width = '';
            // 图片高度
            $img_height = '';

            // 如果是图片，则获取宽度和高度，并判断是否添加水印
            $ext_limit = config('upload_image_ext');
            $ext_limit = $ext_limit == '' ? [] : explode(',', $ext_limit);

            // 缩略图路径
            $thumb_path_name = rtrim($config['domain'], '/').'/'.$key;

            if (preg_grep("/$ext/i", $ext_limit)) {
                $img = Image::open($info);
                $img_width  = $img->width();
                $img_height = $img->height();

                // 生成缩略图
                if ($thumb == '') {
                    if (config('upload_image_thumb') != '') {
                        list($thumb_max_width, $thumb_max_height) = explode(',', config('upload_image_thumb'));

                        $thumb_path_name = $thumb_path_name.'?x-image-process=image/resize';

                        if($thumb_max_width){
                            $thumb_path_name = $thumb_path_name.',w_'.$thumb_max_width;
                        }
                        if($thumb_max_height){
                            $thumb_path_name = $thumb_path_name.',l_'.$thumb_max_height;
                        }
                    }
                } else {
                    if (strtolower($thumb) != 'close') {
                        list($thumb_size, $thumb_type) = explode('|', $thumb);
                        list($thumb_max_width, $thumb_max_height) = explode(',', $thumb_size);

                        $thumb_path_name = $thumb_path_name.'?x-image-process=image/resize';

                        if($thumb_max_width){
                            $thumb_path_name = $thumb_path_name.',w_'.$thumb_max_width;
                        }
                        if($thumb_max_height){
                            $thumb_path_name = $thumb_path_name.',l_'.$thumb_max_height;
                        }
                    }
                }

            }

            $uid = session('user_auth.uid');

            // 获取附件信息
            $data = [
                'uid'    => $uid ? $uid : 1,
                'name'   => $file_info['name'],
                'mime'   => $file_info['type'],
                'path'   => rtrim($config['domain'], '/').'/'.$key,
                'url'    => rtrim($config['domain'], '/').'/'.$key,
                'ext'    => $info->getExtension(),
                'size'   => $info->getSize(),
                'md5'    => $info->hash('md5'),
                'sha1'   => $info->hash('sha1'),
                'thumb'  => $thumb_path_name,
                'module' => $params['module'],
                'driver' => 'huawei_obs',
                'width'  => $img_width,
                'height' => $img_height,
            ];

            if ($file_add = AttachmentModel::create($data)) {
                unset($info);
                // 删除本地临时文件
                @unlink(config('upload_path') . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . $file_info['name']);
                switch ($params['from']) {
                    case 'wangeditor':
                        return $data['url'];
                        break;
                    case 'ueditor':
                        return json([
                            "state" => "SUCCESS",
                            //"url"   => $data['ext']!='gif' && $data['width']>300 && $data['height']>300 ? $data['url']."?x-image-process=style/watermark" : $data['url'], // 返回的地址
                            "url"   => $data['ext']!='gif' && $data['width']>300 && $data['height']>300 ? $data['url']."" : $data['url'], // 返回的地址
                            "title" => $file_info['name'], // 附件名
                        ]);
                        break;
                    case 'editormd':
                        return json([
                            "success" => 1,
                            "message" => '上传成功',
                            "url"     => $data['url'],
                        ]);
                        break;
                    case 'ckeditor':
                        return ck_js(request()->get('CKEditorFuncNum'), $data['path']);
                        break;
                    case 'layim':
                        return json([
                            'code'   => 0,
                            'msg'   => '上传成功',
                            'data'  => [
                                'src'   => $data['url'],
                            ]
                        ]);
                        break;
                    default:
                        return json([
                            'code'   => 1,
                            'info'   => '上传成功',
                            'class'  => 'success',
                            'id'     => $file_add['id'],
                            'path'   => $data['path'],
                            'url'   => $data['url'],
                        ]);
                }
            } else {
                switch ($params['from']) {
                    case 'wangeditor':
                        return "error|上传失败";
                        break;
                    case 'ueditor':
                        return json(['state' => '上传失败']);
                        break;
                    case 'editormd':
                        return json(["success" => 0, "message" => '上传失败']);
                        break;
                    case 'ckeditor':
                        return ck_js(request()->get('CKEditorFuncNum'), '', '上传失败');
                        break;
                    case 'layim':
                        return json(['code'   => 1, 'msg'   => '上传失败', 'data' => []]);
                        break;
                    default:
                        return json(['code' => 0, 'class' => 'danger', 'info' => '上传失败']);
                }
            }
        }
    }

    /**
     * 安装方法
     * @return bool
     */
    public function install(){

        //提示卸载其他的【上传驱动】
        $res = Db::name('admin_hook_plugin')->where(['hook' => 'upload_attachment'])->find();
        if($res){
            $this->error = '请先卸载其他的【上传驱动】后再次尝试安装';
            return false;
        }

        $upload_driver = Db::name('admin_config')->where(['name' => 'upload_driver', 'group' => 'upload'])->find();
        if (!$upload_driver) {
            $this->error = '未找到【上传驱动】配置';
            return false;
        }
        $options = parse_attr($upload_driver['options']);
        if (isset($options[$this->info['name']])) {
            $this->error = '已存在名为【'. $this->info['name'] .'】的上传驱动';
            return false;
        }
        $upload_driver['options'] .= PHP_EOL.$this->info['name'].':'.$this->info['title'];

        $result = Db::name('admin_config')
            ->where(['name' => 'upload_driver', 'group' => 'upload'])
            ->setField('options', $upload_driver['options']);

        if (false === $result) {
            $this->error = '上传驱动设置失败';
            return false;
        }
        return true;
    }

    /**
     * 卸载方法
     * @return bool
     */
    public function uninstall(){
        $upload_driver = Db::name('admin_config')->where(['name' => 'upload_driver', 'group' => 'upload'])->find();
        if ($upload_driver) {
            $options = parse_attr($upload_driver['options']);
            if (isset($options[$this->info['name']])) {
                unset($options[$this->info['name']]);
            }
            $options = implode_attr($options);

            $result = Db::name('admin_config')
                ->where(['name' => 'upload_driver', 'group' => 'upload'])
                ->update(['options' => $options, 'value' => 'local']);

            if (false === $result) {
                $this->error = '上传驱动设置失败';
                return false;
            }
        }
        return true;
    }

}